如何用Html Helpers建立CRUD表單
今天我們要來學的就是相較於用Scaffolding來的更複雜一點的方法,也就是用Html Helpers建立CRUD表單~
雖然說是比較複雜啦,但就是先用EF Core中的Migrations建立資料庫,完成後分別建立CRUD的動作,再用動作去建立檢視而已,拆成單一部份去看還是容易一點的。
那下面就開始實作啦~GoGo!
用EF Core中的Migrations建立資料庫
1️⃣在Models資料夾中建立Employee與Register資料模型
路徑🔗Models/Employee.cs
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public string Department { get; set; }
public string Title { get; set; }
}
路徑🔗Models/Register.cs
{
public class Register
{
public int Id { get; set; }
public string Name { get; set; }
public string Nickname { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public int Gender { get; set; }
public int City { get; set; }
public string Commutermode { get; set; }
public string Comment { get; set; }
public bool Terms { get; set; }
}
}
2️⃣以【Nuget套件管理員】安裝下圖EF Core與SqlServer等相關套件
3️⃣在Data資料夾建立CmsContext類別及種子資料
路徑🔗Data/CmsContext.cs
namespace Mvc7_HtmlHelpers.Data
{
public class CmsContext : DbContext
{
public CmsContext(DbContextOptions<CmsContext> options)
: base(options)
{
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Register> Registers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>().HasData(
new Employee { Id = 1, Name = "David", Mobile = "0933-152667", Email = "david@gmail.com", Department = "總經理室", Title = "CEO" },
new Employee { Id = 2, Name = "Mary", Mobile = "0938-456889", Email = "mary@gmail.com", Department = "人事部", Title = "管理師" },
new Employee { Id = 3, Name = "Joe", Mobile = "0925-331225", Email = "joe@gmail.com", Department = "財務部", Title = "經理" },
new Employee { Id = 4, Name = "Mark", Mobile = "0935-863991", Email = "mark@gmail.com", Department = "業務部", Title = "業務員" },
new Employee { Id = 5, Name = "Rose", Mobile = "0987-335668", Email = "rose@gmail.com", Department = "資訊部", Title = "工程師" }
);
modelBuilder.Entity<Register>().HasData(
new Register { Id = 1, Name = "奚江華", Nickname = "聖殿祭司", Password = "myPassword*", Email = "dotnetcool@gmail.com", City = 4, Gender = 1, Commutermode = "1", Comment = "Nothing", Terms = true }
);
}
}
}
說明📄
1.DbContext➡️負責執行時期的Entity物件管理,包括從資料庫讀取資料、追蹤異動及資料寫入資料庫。
2.DbSet➡️用來查詢和儲存Entity個體資料,LINQ查詢是以DbSet為對象,然後LINQ語法會被轉成SQL查詢語法。
4️⃣在appsettings.json新增「CmsContext」資料庫連線設定
路徑🔗appsettings.json
{
...
"AllowedHosts": "*",
"ConnectionStrings": {
"CmsContext": "Server=(localdb)\\mssqllocaldb;Database=CmsDB;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
5️⃣在DI Container中註冊CmsContext
路徑🔗Program.cs
//取得組態中資料庫連線設定
string connectionString = builder.Configuration.GetConnectionString("CmsContext");
//註冊UEF Core的CmsContext
builder.Services.AddDbContext<CmsContext>(options => options.UseSqlServer(connectionString));
說明📄
在DI Container中註冊CmsContext後,才能在Controller或其他程式中以DI注入服務。在options中設定了兩點:1.使用SQL Server Provider提供者。2.使用CmsContext資料庫連線。
6️⃣在【套件管理主控台】新增MigrationAdd-Migration InitialDB
7️⃣執行「Update-Database」命令更新資料庫Update-Database
顯示員工清單資料
1️⃣在Controllers資料夾新增Employees控制器,以DI注入CmsContext,建立Index()程式讀取員工資料。
路徑🔗Controllers/EmployeesController.cs
public class EmployeesController : Controller
{
private readonly CmsContext _context;
//以DI注入CmsContext
public EmployeesController(CmsContext context)
{
_context = context;
}
// GET: Employees
public async Task<IActionResult> Index()
{
//從資料庫讀取資料,指派給employees物件
var employees = await _context.Employees.ToListAsync();
return View(employees);
}
2️⃣在Index()方法按滑鼠右鍵→【新增檢視】→【Razor檢視】→範本【Empty(沒有模型)】→【新增】
@model IEnumerable<Employee>
@{
ViewData["Title"] = "Index";
}
<table class="table table-striped table-bordered table-hover">
<caption><h2>員工資料列表</h2></caption>
<thead>
<tr>
<th>
@Html.DisplayNameFor(m => m.Name)
</th>
<th>
@Html.DisplayNameFor(m => m.Mobile)
</th>
<th>
@Html.DisplayNameFor(m => m.Email)
</th>
<th>
@Html.DisplayNameFor(m => m.Department)
</th>
<th>
@Html.DisplayNameFor(m => m.Title)
</th>
<th>異動</th>
</tr>
</thead>
<tbody>
@foreach (var m in Model)
{
<tr>
<td>
@Html.DisplayFor(x => m.Name)
</td>
<td>
@Html.DisplayFor(x => m.Mobile)
</td>
<td>
@Html.DisplayFor(x => m.Email)
</td>
<td>
@Html.DisplayFor(x => m.Department)
</td>
<td>
@Html.DisplayFor(x => m.Title)
</td>
<td>
<a asp-action="Edit" asp-route-id="@m.Id" class="btn btn-info">編輯</a>
<a asp-action="Details" asp-route-id="@m.Id" class="btn btn-primary">明細</a>
<a asp-action="Delete" asp-route-id="@m.Id" class="btn btn-danger">刪除</a>
</td>
</tr>
}
</tbody>
</table>
<p>
<a asp-action="Create" class="btn btn-warning">新增員工資料</a>
</p>
顯示員工明細資料
1️⃣在Employees控制器建立Details方法,主要利用FirstOrDefaultAsync()方法查詢員工資料,其餘只是防呆的判斷程式。
路徑🔗Controllers/EmployeesController.cs
// GET: Employees/Details/5
public async Task<IActionResult> Details(int? id)
{
//檢查是否有員工Id的判斷
if (id == null || _context.Employees == null)
{
var msgObject = new
{
statuscode = StatusCodes.Status400BadRequest,
error = "無效的請求,必須提供Id編號!",
url = "The url example : /Employees/Details/5"
};
return new BadRequestObjectResult(msgObject);
}
//以Id找尋員工資料
var employee = await _context.Employees.FirstOrDefaultAsync(m => m.Id == id);
//如果沒有找到員工,回傳NotFound
if (employee == null)
{
return NotFound();
}
return View(employee);
}
2️⃣建立檢視,如上一動作之方法
@model Employee
@{
ViewData["Title"] = "Create";
}
<h4 class="alert alert-danger">員工個人資料明細</h4>
<div>
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(m => m.Name)
</dt>
<dd class="col-sm-9">
@Html.DisplayFor(m => m.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(m => m.Mobile)
</dt>
<dd class="col-sm-9">
@Html.DisplayFor(m => m.Mobile)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(m => m.Email)
</dt>
<dd class="col-sm-9">
@Html.DisplayFor(m => m.Email)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(m => m.Department)
</dt>
<dd class="col-sm-9">
@Html.DisplayFor(m => m.Department)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(m => m.Title)
</dt>
<dd class="col-sm-9">
@Html.DisplayFor(m => m.Title)
</dd>
</dl>
</div>
<div>
<a asp-action="Edit" asp-route-id="@Model.Id">編輯</a> |
<a asp-action="Index">返回員工列表</a>
</div>
新增員工資料
1️⃣在Employees控制器建立Create方法
// GET: Employees/Create
[HttpGet]
public IActionResult Create()
{
return View();
}
// POST: Employees/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,Mobile,Email,Department,Title")] Employee employee)
{
//用ModelState.IsValid判斷資料是否通過驗證
if (ModelState.IsValid)
{
//將entity加入DbSet
_context.Employees.Add(employee);
//_context.Add<Employee>(employee);
//_context.Add(employee);
//將資料異動儲存到資料庫
await _context.SaveChangesAsync();
//導向至Index動作方法
return RedirectToAction(nameof(Index));
}
return View(employee);
}
2️⃣建立檢視,如上一動作之方法
3️⃣利用Data Annotations為Model加上驗證規則
路徑🔗Model/Employee.cs
namespace Mvc7_HtmlHelpers.Models
{
public class Employee
{
public int Id { get; set; }
[Required]
[StringLength(20, MinimumLength = 3, ErrorMessage = "最少需3個字元!")]
public string Name { get; set; }
[Required]
[RegularExpression(@"^\09d{2}\-?\d{3}\-?\d{3}$", ErrorMessage = "需為09xx-xxx-xxx格式")]
public string Mobile { get; set; }
[Required(ErrorMessage = "請輸入Email")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required(ErrorMessage = "請輸入Department")]
public string Department { get; set; }
[Required(ErrorMessage = "請輸入Title")]
public string Title { get; set; }
}
}
編輯員工資料
1️⃣在Employees控制器建立Edit方法
// GET: Employees/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null || _context.Employees == null)
{
return NotFound();
}
var employee = await _context.Employees.FindAsync(id);
if (employee == null)
{
return NotFound();
}
return View(employee);
}
// POST: Employees/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Mobile,Email,Department,Title")] Employee employee)
{
//檢查編輯id與Entity的Id是否相等
if (id != employee.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
//更新employee實體
_context.Employees.Update(employee);
//_context.Update<Employee>(employee);
//_context.Update(employee);
await _context.SaveChangesAsync(); //將資料異動儲存到資料庫
}
catch (DbUpdateConcurrencyException)
{
if (!EmployeeExists(employee.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(employee);
}
2️⃣建立檢視,如上一動作之方法
刪除員工資料
1️⃣在Employees控制器建立Delete方法
// GET: Employees/Delete/5
public async Task<IActionResult> Delete(int? id)
{
//檢查是否有提供id
if (id == null || _context.Employees == null)
{
return NotFound();
}
//以Id找尋員工資料
var employee = await _context.Employees
.FirstOrDefaultAsync(m => m.Id == id);
//如果沒有找到員工,回傳NotFound
if (employee == null)
{
return NotFound();
}
return View(employee);
}
// POST: Employees/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
if (_context.Employees == null)
{
return Problem("Entity set 'CmsContext.Employees' is null.");
}
//以Id找尋Entity,然後刪除
var employee = await _context.Employees.FindAsync(id);
if (employee != null)
{
//將該筆資料移除
_context.Employees.Remove(employee);
await _context.SaveChangesAsync(); //將資料異動儲存到資料庫
}
return RedirectToAction(nameof(Index));
}
private bool EmployeeExists(int id)
{
return _context.Employees.Any(e => e.Id == id);
}
}
}
2️⃣建立檢視,如上一動作之方法
以上就是如何用Html Helpers建立完整CRUD表單的方法啦~
那麼今天的文章就到這邊結束啦~明天見~See ya!(。•̀ᴗ-)